package com.fuyun.rpc.server.protocol;

import com.fuyun.rpc.common.serializer.Serializer;
import com.fuyun.rpc.server.config.RpcConfig;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import lombok.extern.slf4j.Slf4j;

/**
 * @author: zrq1351
 * @date: 2025/2/20
 */
@Slf4j
public class VertxHttpServerHandler extends AbstractServerHandler implements Handler<HttpServerRequest> {

	public VertxHttpServerHandler(Serializer serializer, RpcConfig rpcConfig) {
		super(serializer, rpcConfig);
	}

	/**
	 * 处理HTTP服务器请求的方法 该方法覆写自父类，用于处理接收到的HTTP请求 它首先记录请求的URI和方法，然后处理请求体
	 *
	 * @param httpServerRequest HttpServerRequest对象，包含客户端发送的所有请求信息
	 */
	@Override
	public void handle(HttpServerRequest httpServerRequest) {
		log.info("已收到请求 {} {}", httpServerRequest.uri(), httpServerRequest.method());

		httpServerRequest.bodyHandler(buffer -> {
			log.info("接收体长度: {}", buffer.length());
			processData(buffer, new HttpServerConnection(httpServerRequest));
		});
	}

	/**
	 * 发送响应数据的方法 该方法覆写自父类，用于向客户端发送响应数据。 它首先记录响应数据的长度，然后使用给定的服务器连接对象发送响应数据。
	 *
	 * @param connection    服务器连接对象，用于发送数据
	 * @param responseBuffer 包含响应数据的缓冲区
	 */
	@Override
	protected void sendResponse(ServerConnection connection, Buffer responseBuffer) {
		if (connection instanceof HttpServerConnection) {
			((HttpServerConnection)connection).sendResponse(responseBuffer);
		}
	}

	/**
	 * 发送错误响应的方法 该方法用于向客户端发送错误信息
	 *
	 * @param connection 服务器连接对象，用于发送数据
	 * @param message    错误消息
	 */
	@Override
	protected void sendErrorResponse(ServerConnection connection, String message) {
		if (connection instanceof HttpServerConnection) {
			((HttpServerConnection)connection).sendErrorResponse(message);
		}
	}

	/**
	 * HTTP服务器连接实现类 该类实现了ServerConnection接口，用于处理HTTP连接的相关操作
	 */
	private static class HttpServerConnection implements ServerConnection {
		private final HttpServerRequest httpServerRequest;

		public HttpServerConnection(HttpServerRequest httpServerRequest) {
			this.httpServerRequest = httpServerRequest;
		}

		/**
		 * 发送响应数据的方法 该方法用于向客户端发送响应数据 它首先记录响应数据的长度，然后使用HTTP服务器请求对象发送响应数据
		 *
		 * @param buffer 包含响应数据的缓冲区
		 */
		public void sendResponse(Buffer buffer) {
			log.info("响应正文长度: {}", buffer.length());
			httpServerRequest.response()
				.end(buffer);
		}

		/**
		 * 发送错误响应的方法 该方法用于向客户端发送错误响应 它设置HTTP状态码为500（内部服务器错误），然后发送错误消息
		 *
		 * @param message 错误消息
		 */
		public void sendErrorResponse(String message) {
			log.error("发送错误响应: {}", message);
			httpServerRequest.response()
				.setStatusCode(500)
				.end(message);
		}

		@Override
		public void close() {
			// HTTP连接由底层框架管理，无需手动关闭
		}
	}
}